﻿namespace Widgetsphere.Autos.API.FacetedNavigation
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.ServiceModel;
    using HP.Datastore.Common;

    [Serializable]
    public partial class ListingDerivedField : IDerivedField
    {
        public ListingItem.FieldConstants Field { get; set; }
        public AggregateOperationConstants Action { get; set; }

        string IDerivedField.Field
        {
            get { return this.Field.ToString(); }
            set { this.Field = (ListingItem.FieldConstants)Enum.Parse(typeof(ListingItem.FieldConstants), value); }
        }
    }

    [Serializable]
    public partial class ListingDerivedFieldValue : ListingDerivedField, IDerivedFieldValue
    {
        public object Value { get; set; }
    }

    [Serializable]
    public partial class ListingItem : HP.Datastore.Common.IListingItem
    {
        public ListingItem()
        {
            _dimensionList = new List<DimensionItem>();
        }

        public DimensionStore AllDimensions { get; private set; }

        internal ListingItem(HP.Datastore.Common.DataItem item, ListingResults results, FieldDefinition[] fields)
            : this()
        {

            this.AllDimensions = new DimensionStore(null);

            var fl = fields.ToList();
            this.AutoID = (int)item.ItemArray[fl.IndexOf(fl.First(x => x.Name == "AutoID"))];
            this.Make = (string)item.ItemArray[fl.IndexOf(fl.First(x => x.Name == "Make"))];
            this.Model = (string)item.ItemArray[fl.IndexOf(fl.First(x => x.Name == "Model"))];
            this.State = (string)item.ItemArray[fl.IndexOf(fl.First(x => x.Name == "State"))];
            this.ExteriorColor = (string)item.ItemArray[fl.IndexOf(fl.First(x => x.Name == "ExteriorColor"))];
            this.InteriorColor = (string)item.ItemArray[fl.IndexOf(fl.First(x => x.Name == "InteriorColor"))];
            this.Condition = (string)item.ItemArray[fl.IndexOf(fl.First(x => x.Name == "Condition"))];
            this.Mileage = (int?)item.ItemArray[fl.IndexOf(fl.First(x => x.Name == "Mileage"))];
            this.Price = (int?)item.ItemArray[fl.IndexOf(fl.First(x => x.Name == "Price"))];
            this.Transmission = (string)item.ItemArray[fl.IndexOf(fl.First(x => x.Name == "Transmission"))];
            this.Year = (int?)item.ItemArray[fl.IndexOf(fl.First(x => x.Name == "Year"))];
            this.City = (string)item.ItemArray[fl.IndexOf(fl.First(x => x.Name == "City"))];
            this.Location = (HP.Datastore.Common.GeoCode)item.ItemArray[fl.IndexOf(fl.First(x => x.Name == "Location"))];
            this.Metro = (string)item.ItemArray[fl.IndexOf(fl.First(x => x.Name == "Metro"))];
            this.PostDate = (DateTime?)item.ItemArray[fl.IndexOf(fl.First(x => x.Name == "PostDate"))];
            this.ZIP = (string)item.ItemArray[fl.IndexOf(fl.First(x => x.Name == "ZIP"))];
            this.VIN = (string)item.ItemArray[fl.IndexOf(fl.First(x => x.Name == "VIN"))];
            this.UserId = (int?)item.ItemArray[fl.IndexOf(fl.First(x => x.Name == "UserId"))];
            this.Title = (string)item.ItemArray[fl.IndexOf(fl.First(x => x.Name == "Title"))];
            this.FuelType = (string)item.ItemArray[fl.IndexOf(fl.First(x => x.Name == "FuelType"))];
            this.Description = (string)item.ItemArray[fl.IndexOf(fl.First(x => x.Name == "Description"))];
            this.Dealer = (string)item.ItemArray[fl.IndexOf(fl.First(x => x.Name == "Dealer"))];
            this.BodyType = (string)item.ItemArray[fl.IndexOf(fl.First(x => x.Name == "BodyType"))];

            //Add extra fields that have been dynamically added
            if (item.ItemArray.Length > 23)
            {
                this.ExtraValues = new Dictionary<string, string>();
                for (var ii = 23; ii < item.ItemArray.Length; ii++)
                {
                    this.ExtraValues.Add(fields[ii].Name, null);
                    if (item.ItemArray[ii] != null)
                        this.ExtraValues[fields[ii].Name] = item.ItemArray[ii].ToString();
                }
            }

            IRefinementItem r;
            r = results.AllDimensions.BodyTypeDimension.GetRefinementByValue(this.BodyType);
            if (r != null && this.BodyType != null)
            {
                var d = ((System.ICloneable)results.AllDimensions.BodyTypeDimension).Clone() as DimensionItem;
                d.RefinementList.RemoveAll(x => x.FieldValue != this.BodyType);
                d.RefinementList.First().Count = 1;
                _dimensionList.Add(d);
                this.AllDimensions.MasterList.Add(d);
            }

            r = results.AllDimensions.ConditionDimension.GetRefinementByValue(this.Condition);
            if (r != null && this.Condition != null)
            {
                var d = ((System.ICloneable)results.AllDimensions.ConditionDimension).Clone() as DimensionItem;
                d.RefinementList.RemoveAll(x => x.FieldValue != this.Condition);
                d.RefinementList.First().Count = 1;
                _dimensionList.Add(d);
                this.AllDimensions.MasterList.Add(d);
            }

            r = results.AllDimensions.ExteriorColorDimension.GetRefinementByValue(this.ExteriorColor);
            if (r != null && this.ExteriorColor != null)
            {
                var d = ((System.ICloneable)results.AllDimensions.ExteriorColorDimension).Clone() as DimensionItem;
                d.RefinementList.RemoveAll(x => x.FieldValue != this.ExteriorColor);
                d.RefinementList.First().Count = 1;
                _dimensionList.Add(d);
                this.AllDimensions.MasterList.Add(d);
            }

            r = results.AllDimensions.InteriorColorDimension.GetRefinementByValue(this.InteriorColor);
            if (r != null && this.InteriorColor != null)
            {
                var d = ((System.ICloneable)results.AllDimensions.InteriorColorDimension).Clone() as DimensionItem;
                d.RefinementList.RemoveAll(x => x.FieldValue != this.InteriorColor);
                d.RefinementList.First().Count = 1;
                _dimensionList.Add(d);
                this.AllDimensions.MasterList.Add(d);
            }

            r = results.AllDimensions.MakeDimension.GetRefinementByValue(this.Make);
            if (r != null && this.Make != null)
            {
                var d = ((System.ICloneable)results.AllDimensions.MakeDimension).Clone() as DimensionItem;
                d.RefinementList.RemoveAll(x => x.FieldValue != this.Make);
                d.RefinementList.First().Count = 1;
                _dimensionList.Add(d);
                this.AllDimensions.MasterList.Add(d);
            }

            r = results.AllDimensions.MetroDimension.GetRefinementByValue(this.Metro);
            if (r != null && this.Metro != null)
            {
                var d = ((System.ICloneable)results.AllDimensions.MetroDimension).Clone() as DimensionItem;
                d.RefinementList.RemoveAll(x => x.FieldValue != this.Metro);
                d.RefinementList.First().Count = 1;
                _dimensionList.Add(d);
                this.AllDimensions.MasterList.Add(d);
            }

            if (this.Mileage != null)
            {
                r = results.AllDimensions.MileageDimension.GetRefinementByMinValue(FloorToNearest(this.Mileage.Value, 5000));
                if (r != null)
                {
                    var d = ((System.ICloneable)results.AllDimensions.MileageDimension).Clone() as DimensionItem;
                    d.RefinementList.RemoveAll(x => x.MinValue != FloorToNearest(this.Mileage.Value, 5000));
                    d.RefinementList.First().Count = 1;
                    _dimensionList.Add(d);
                    this.AllDimensions.MasterList.Add(d);
                }
            }

            r = results.AllDimensions.ModelDimension.GetRefinementByValue(this.Model);
            if (r != null && this.Model != null)
            {
                var d = ((System.ICloneable)results.AllDimensions.ModelDimension).Clone() as DimensionItem;
                d.RefinementList.RemoveAll(x => x.FieldValue != this.Model);
                d.RefinementList.First().Count = 1;
                _dimensionList.Add(d);
                this.AllDimensions.MasterList.Add(d);
            }

            if (this.Price != null)
            {
                r = results.AllDimensions.PriceDimension.GetRefinementByMinValue(FloorToNearest(this.Price.Value, 5000));
                if (r != null)
                {
                    var d = ((System.ICloneable)results.AllDimensions.PriceDimension).Clone() as DimensionItem;
                    d.RefinementList.RemoveAll(x => x.MinValue != FloorToNearest(this.Price.Value, 5000));
                    d.RefinementList.First().Count = 1;
                    _dimensionList.Add(d);
                    this.AllDimensions.MasterList.Add(d);
                }
            }

            r = results.AllDimensions.StateDimension.GetRefinementByValue(this.State);
            if (r != null && this.State != null)
            {
                var d = ((System.ICloneable)results.AllDimensions.StateDimension).Clone() as DimensionItem;
                d.RefinementList.RemoveAll(x => x.FieldValue != this.State);
                d.RefinementList.First().Count = 1;
                _dimensionList.Add(d);
                this.AllDimensions.MasterList.Add(d);
            }

            r = results.AllDimensions.TransmissionDimension.GetRefinementByValue(this.Transmission);
            if (r != null && this.Transmission != null)
            {
                var d = ((System.ICloneable)results.AllDimensions.TransmissionDimension).Clone() as DimensionItem;
                d.RefinementList.RemoveAll(x => x.FieldValue != this.Transmission);
                d.RefinementList.First().Count = 1;
                _dimensionList.Add(d);
                this.AllDimensions.MasterList.Add(d);
            }

            r = results.AllDimensions.YearDimension.GetRefinementByValue(this.Year.ToString());
            if (r != null && this.Year != null)
            {
                var d = ((System.ICloneable)results.AllDimensions.YearDimension).Clone() as DimensionItem;
                d.RefinementList.RemoveAll(x => x.FieldValue != this.Year.ToString());
                d.RefinementList.First().Count = 1;
                _dimensionList.Add(d);
                this.AllDimensions.MasterList.Add(d);
            }

        }

        public Dictionary<string, string> ExtraValues { get; set; }
        public int AutoID { get; set; }
        public string Make { get; set; }
        public string Model { get; set; }
        public string State { get; set; }
        public string ExteriorColor { get; set; }
        public string InteriorColor { get; set; }
        public string Condition { get; set; }
        public int? Mileage { get; set; }
        public int? Price { get; set; }
        public string Transmission { get; set; }
        public int? Year { get; set; }
        public string City { get; set; }
        public HP.Datastore.Common.GeoCode Location { get; set; }
        public string Metro { get; set; }
        public DateTime? PostDate { get; set; }
        public string ZIP { get; set; }
        public string VIN { get; set; }
        public int? UserId { get; set; }
        public string Title { get; set; }
        public string FuelType { get; set; }
        public string Description { get; set; }
        public string Dealer { get; set; }
        public string BodyType { get; set; }

        public enum FieldConstants
        {
            AutoID,
            Make,
            Model,
            State,
            ExteriorColor,
            InteriorColor,
            Condition,
            Mileage,
            Price,
            Transmission,
            Year,
            City,
            Location,
            Metro,
            PostDate,
            ZIP,
            VIN,
            UserId,
            Title,
            FuelType,
            Description,
            Dealer,
            BodyType,
        }

        System.Type IListingItem.GetFieldEnum()
        {
            return typeof(FieldConstants);
        }

        internal List<DimensionItem> _dimensionList = new List<DimensionItem>();

        public IEnumerable<DimensionItem> DimensionList
        {
            get { return _dimensionList; }
        }

        private static long FloorToNearest(long d, long n)
        {
            if (n <= 0) throw new Exception("The rounding operation cannot be performed.");
            return d - (d % n);
        }

        public HP.Datastore.Common.DataItem ToTransfer(RepositorySchema schema)
        {
            var retval = new HP.Datastore.Common.DataItem();
            var l = new List<object>();
            var evList = this.ExtraValues ?? new Dictionary<string, string>();
            foreach (var field in schema.FieldList)
            {
                if (1 == 0) ;
                else if (field.Name == "AutoID") l.Add(this.AutoID);
                else if (field.Name == "Make") l.Add(this.Make);
                else if (field.Name == "Model") l.Add(this.Model);
                else if (field.Name == "State") l.Add(this.State);
                else if (field.Name == "ExteriorColor") l.Add(this.ExteriorColor);
                else if (field.Name == "InteriorColor") l.Add(this.InteriorColor);
                else if (field.Name == "Condition") l.Add(this.Condition);
                else if (field.Name == "Mileage") l.Add(this.Mileage);
                else if (field.Name == "Price") l.Add(this.Price);
                else if (field.Name == "Transmission") l.Add(this.Transmission);
                else if (field.Name == "Year") l.Add(this.Year);
                else if (field.Name == "City") l.Add(this.City);
                else if (field.Name == "Location") l.Add(this.Location);
                else if (field.Name == "Metro") l.Add(this.Metro);
                else if (field.Name == "PostDate") l.Add(this.PostDate);
                else if (field.Name == "ZIP") l.Add(this.ZIP);
                else if (field.Name == "VIN") l.Add(this.VIN);
                else if (field.Name == "UserId") l.Add(this.UserId);
                else if (field.Name == "Title") l.Add(this.Title);
                else if (field.Name == "FuelType") l.Add(this.FuelType);
                else if (field.Name == "Description") l.Add(this.Description);
                else if (field.Name == "Dealer") l.Add(this.Dealer);
                else if (field.Name == "BodyType") l.Add(this.BodyType);
                else
                {
                    if (evList.Any(x => x.Key == field.Name)) l.Add(evList[field.Name]);
                    else l.Add(null);
                }
            }
            retval.ItemArray = l.ToArray();
            return retval;
        }

        IDimensionStore IListingItem.AllDimensions
        {
            get { return this.AllDimensions; }
        }

        Dictionary<string, string> IListingItem.ExtraValues
        {
            get { return this.ExtraValues; }
            set { this.ExtraValues = value; }
        }

        DataItem IListingItem.ToTransfer(RepositorySchema schema)
        {
            return this.ToTransfer(schema);
        }

        IEnumerable<DimensionItem> IListingItem.DimensionList
        {
            get { return this.DimensionList; }
        }

    }

    [Serializable]
    public partial class ListingQuery : HP.Datastore.Common.BaseListingQuery, System.ICloneable
    {
        public ListingQuery()
            : base()
        {
        }

        internal ListingQuery(HP.Datastore.Common.DataQueryResults results)
            : this()
        {
            var query = results.Query;
            this.DimensionValueList.AddRange(query.DimensionValueList);
            this.PageOffset = query.PageOffset;
            this.RecordsPerPage = query.RecordsPerPage;
            this.Keyword = query.Keyword;
            this.PageName = query.PageName;
            this.NonParsedFieldList = new NamedItemList();
            this.IncludeEmptyDimensions = query.IncludeEmptyDimensions;
            if (query.NonParsedFieldList != null)
                this.NonParsedFieldList.AddRange(query.NonParsedFieldList);

            #region Field Filters
            if (query.FieldFilters != null)
            {
                foreach (var ff in query.FieldFilters)
                {
                    switch (ff.Name)
                    {
                        case "AutoID":
                            this.FieldFilters.Add(new FieldFilterAutoID { AutoID = (int?)ff.Value, Comparer = ff.Comparer });
                            break;
                        case "Make":
                            this.FieldFilters.Add(new FieldFilterMake { Make = (string)ff.Value, Comparer = ff.Comparer });
                            break;
                        case "Model":
                            this.FieldFilters.Add(new FieldFilterModel { Model = (string)ff.Value, Comparer = ff.Comparer });
                            break;
                        case "State":
                            this.FieldFilters.Add(new FieldFilterState { State = (string)ff.Value, Comparer = ff.Comparer });
                            break;
                        case "ExteriorColor":
                            this.FieldFilters.Add(new FieldFilterExteriorColor { ExteriorColor = (string)ff.Value, Comparer = ff.Comparer });
                            break;
                        case "InteriorColor":
                            this.FieldFilters.Add(new FieldFilterInteriorColor { InteriorColor = (string)ff.Value, Comparer = ff.Comparer });
                            break;
                        case "Condition":
                            this.FieldFilters.Add(new FieldFilterCondition { Condition = (string)ff.Value, Comparer = ff.Comparer });
                            break;
                        case "Mileage":
                            this.FieldFilters.Add(new FieldFilterMileage { Mileage = (int?)ff.Value, Comparer = ff.Comparer });
                            break;
                        case "Price":
                            this.FieldFilters.Add(new FieldFilterPrice { Price = (int?)ff.Value, Comparer = ff.Comparer });
                            break;
                        case "Transmission":
                            this.FieldFilters.Add(new FieldFilterTransmission { Transmission = (string)ff.Value, Comparer = ff.Comparer });
                            break;
                        case "Year":
                            this.FieldFilters.Add(new FieldFilterYear { Year = (int?)ff.Value, Comparer = ff.Comparer });
                            break;
                        case "City":
                            this.FieldFilters.Add(new FieldFilterCity { City = (string)ff.Value, Comparer = ff.Comparer });
                            break;
                        case "Location":
                            this.FieldFilters.Add(new FieldFilterLocation()
                            {
                                Latitude = ((HP.Datastore.Common.GeoCodeFieldFilter)ff).Latitude,
                                Longitude = ((HP.Datastore.Common.GeoCodeFieldFilter)ff).Longitude,
                                Radius = ((HP.Datastore.Common.GeoCodeFieldFilter)ff).Radius,
                                Comparer = ff.Comparer,
                            });
                            break;
                        case "Metro":
                            this.FieldFilters.Add(new FieldFilterMetro { Metro = (string)ff.Value, Comparer = ff.Comparer });
                            break;
                        case "PostDate":
                            this.FieldFilters.Add(new FieldFilterPostDate { PostDate = (DateTime?)ff.Value, Comparer = ff.Comparer });
                            break;
                        case "ZIP":
                            this.FieldFilters.Add(new FieldFilterZIP { ZIP = (string)ff.Value, Comparer = ff.Comparer });
                            break;
                        case "VIN":
                            this.FieldFilters.Add(new FieldFilterVIN { VIN = (string)ff.Value, Comparer = ff.Comparer });
                            break;
                        case "UserId":
                            this.FieldFilters.Add(new FieldFilterUserId { UserId = (int?)ff.Value, Comparer = ff.Comparer });
                            break;
                        case "Title":
                            this.FieldFilters.Add(new FieldFilterTitle { Title = (string)ff.Value, Comparer = ff.Comparer });
                            break;
                        case "FuelType":
                            this.FieldFilters.Add(new FieldFilterFuelType { FuelType = (string)ff.Value, Comparer = ff.Comparer });
                            break;
                        case "Description":
                            this.FieldFilters.Add(new FieldFilterDescription { Description = (string)ff.Value, Comparer = ff.Comparer });
                            break;
                        case "Dealer":
                            this.FieldFilters.Add(new FieldFilterDealer { Dealer = (string)ff.Value, Comparer = ff.Comparer });
                            break;
                        case "BodyType":
                            this.FieldFilters.Add(new FieldFilterBodyType { BodyType = (string)ff.Value, Comparer = ff.Comparer });
                            break;
                        default:
                            this.FieldFilters.Add(ff);
                            break;
                    }
                }
            }
            #endregion

            #region Field Sorts
            if (query.FieldSorts != null)
            {
                foreach (var fs in query.FieldSorts)
                {
                    switch (fs.Name)
                    {
                        case "AutoID":
                            this.FieldSorts.Add(new FieldSortAutoID { Name = fs.Name, SortDirection = fs.SortDirection });
                            break;
                        case "Make":
                            this.FieldSorts.Add(new FieldSortMake { Name = fs.Name, SortDirection = fs.SortDirection });
                            break;
                        case "Model":
                            this.FieldSorts.Add(new FieldSortModel { Name = fs.Name, SortDirection = fs.SortDirection });
                            break;
                        case "State":
                            this.FieldSorts.Add(new FieldSortState { Name = fs.Name, SortDirection = fs.SortDirection });
                            break;
                        case "ExteriorColor":
                            this.FieldSorts.Add(new FieldSortExteriorColor { Name = fs.Name, SortDirection = fs.SortDirection });
                            break;
                        case "InteriorColor":
                            this.FieldSorts.Add(new FieldSortInteriorColor { Name = fs.Name, SortDirection = fs.SortDirection });
                            break;
                        case "Condition":
                            this.FieldSorts.Add(new FieldSortCondition { Name = fs.Name, SortDirection = fs.SortDirection });
                            break;
                        case "Mileage":
                            this.FieldSorts.Add(new FieldSortMileage { Name = fs.Name, SortDirection = fs.SortDirection });
                            break;
                        case "Price":
                            this.FieldSorts.Add(new FieldSortPrice { Name = fs.Name, SortDirection = fs.SortDirection });
                            break;
                        case "Transmission":
                            this.FieldSorts.Add(new FieldSortTransmission { Name = fs.Name, SortDirection = fs.SortDirection });
                            break;
                        case "Year":
                            this.FieldSorts.Add(new FieldSortYear { Name = fs.Name, SortDirection = fs.SortDirection });
                            break;
                        case "City":
                            this.FieldSorts.Add(new FieldSortCity { Name = fs.Name, SortDirection = fs.SortDirection });
                            break;
                        case "Metro":
                            this.FieldSorts.Add(new FieldSortMetro { Name = fs.Name, SortDirection = fs.SortDirection });
                            break;
                        case "PostDate":
                            this.FieldSorts.Add(new FieldSortPostDate { Name = fs.Name, SortDirection = fs.SortDirection });
                            break;
                        case "ZIP":
                            this.FieldSorts.Add(new FieldSortZIP { Name = fs.Name, SortDirection = fs.SortDirection });
                            break;
                        case "VIN":
                            this.FieldSorts.Add(new FieldSortVIN { Name = fs.Name, SortDirection = fs.SortDirection });
                            break;
                        case "UserId":
                            this.FieldSorts.Add(new FieldSortUserId { Name = fs.Name, SortDirection = fs.SortDirection });
                            break;
                        case "Title":
                            this.FieldSorts.Add(new FieldSortTitle { Name = fs.Name, SortDirection = fs.SortDirection });
                            break;
                        case "FuelType":
                            this.FieldSorts.Add(new FieldSortFuelType { Name = fs.Name, SortDirection = fs.SortDirection });
                            break;
                        case "Description":
                            this.FieldSorts.Add(new FieldSortDescription { Name = fs.Name, SortDirection = fs.SortDirection });
                            break;
                        case "Dealer":
                            this.FieldSorts.Add(new FieldSortDealer { Name = fs.Name, SortDirection = fs.SortDirection });
                            break;
                        case "BodyType":
                            this.FieldSorts.Add(new FieldSortBodyType { Name = fs.Name, SortDirection = fs.SortDirection });
                            break;
                        default:
                            this.FieldSorts.Add(fs);
                            break;
                    }
                }
            }
            #endregion

        }

        public ListingQuery(string url)
            : this()
        {
            if (string.IsNullOrEmpty(url)) return;
            if (url.Contains("%")) url = System.Web.HttpUtility.UrlDecode(url);
            var originalUrl = url;

            var pageBreak = url.IndexOf('?');
            if (pageBreak != -1 && pageBreak < url.Length - 1)
            {
                this.PageName = url.Substring(0, pageBreak);
                url = url.Substring(pageBreak + 1, url.Length - pageBreak - 1);
            }
            else
            {
                this.PageName = url;
                return;
            }

            #region Parse Query String
            var tuplets = url.Split('&');
            foreach (var gset in tuplets)
            {
                var values = gset.Split(new char[] { '=' }, StringSplitOptions.RemoveEmptyEntries);
                if (values.Length == 2)
                {
                    switch (values[0])
                    {
                        case "_ied":
                            if (values[1] == "1")
                                this.IncludeEmptyDimensions = true;
                            break;
                        case "d":
                            {
                                var dValues = values[1].Split(new char[] { '+', ' ' }, StringSplitOptions.RemoveEmptyEntries);
                                foreach (var dvidxV in dValues)
                                {
                                    long dvidx;
                                    if (long.TryParse(dvidxV, out dvidx))
                                        this.DimensionValueList.Add(dvidx);
                                }
                            }
                            break;
                        case "po":
                            {
                                int po;
                                if (int.TryParse(values[1], out po))
                                    this.PageOffset = po;
                            }
                            break;
                        case "rpp":
                            {
                                int rpp;
                                if (int.TryParse(values[1], out rpp))
                                    this.RecordsPerPage = rpp;
                            }
                            break;
                        case "ff":
                            #region Filters
                            {
                                var filters = values[1].Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
                                foreach (var s in filters)
                                {
                                    var svalues = s.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                                    if (svalues.Length >= 3)
                                    {
                                        HP.Datastore.Common.ComparisonConstants enumValue;
                                        if (Enum.TryParse<HP.Datastore.Common.ComparisonConstants>(svalues[1], true, out enumValue))
                                        {
                                            switch (svalues[0].ToLower())
                                            {
                                                case "autoid":
                                                    int autoidValue;
                                                    if (int.TryParse(svalues[2], out autoidValue))
                                                        this.FieldFilters.Add(new FieldFilterAutoID() { Name = "AutoID", Comparer = enumValue, AutoID = autoidValue });
                                                    if (enumValue == HP.Datastore.Common.ComparisonConstants.Between)
                                                    {
                                                        if (svalues.Length > 3)
                                                        {
                                                            if (int.TryParse(svalues[3], out autoidValue))
                                                                this.FieldFilters.Last().Value2 = autoidValue;
                                                            else
                                                                throw new Exception("The URL for field filter 'AutoID' is invalid!");
                                                        }
                                                        else
                                                            throw new Exception("The URL for field filter 'AutoID' is invalid!");
                                                    }
                                                    break;
                                                case "bodytype":
                                                    this.FieldFilters.Add(new FieldFilterBodyType() { Name = "BodyType", Comparer = enumValue, BodyType = svalues[2] });
                                                    if (enumValue == HP.Datastore.Common.ComparisonConstants.Between)
                                                    {
                                                        if (svalues.Length > 3)
                                                            this.FieldFilters.Last().Value2 = svalues[3];
                                                        else
                                                            throw new Exception("The URL for field filter 'BodyType' is invalid!");
                                                    }
                                                    break;
                                                case "city":
                                                    this.FieldFilters.Add(new FieldFilterCity() { Name = "City", Comparer = enumValue, City = svalues[2] });
                                                    if (enumValue == HP.Datastore.Common.ComparisonConstants.Between)
                                                    {
                                                        if (svalues.Length > 3)
                                                            this.FieldFilters.Last().Value2 = svalues[3];
                                                        else
                                                            throw new Exception("The URL for field filter 'City' is invalid!");
                                                    }
                                                    break;
                                                case "condition":
                                                    this.FieldFilters.Add(new FieldFilterCondition() { Name = "Condition", Comparer = enumValue, Condition = svalues[2] });
                                                    if (enumValue == HP.Datastore.Common.ComparisonConstants.Between)
                                                    {
                                                        if (svalues.Length > 3)
                                                            this.FieldFilters.Last().Value2 = svalues[3];
                                                        else
                                                            throw new Exception("The URL for field filter 'Condition' is invalid!");
                                                    }
                                                    break;
                                                case "dealer":
                                                    this.FieldFilters.Add(new FieldFilterDealer() { Name = "Dealer", Comparer = enumValue, Dealer = svalues[2] });
                                                    if (enumValue == HP.Datastore.Common.ComparisonConstants.Between)
                                                    {
                                                        if (svalues.Length > 3)
                                                            this.FieldFilters.Last().Value2 = svalues[3];
                                                        else
                                                            throw new Exception("The URL for field filter 'Dealer' is invalid!");
                                                    }
                                                    break;
                                                case "description":
                                                    this.FieldFilters.Add(new FieldFilterDescription() { Name = "Description", Comparer = enumValue, Description = svalues[2] });
                                                    if (enumValue == HP.Datastore.Common.ComparisonConstants.Between)
                                                    {
                                                        if (svalues.Length > 3)
                                                            this.FieldFilters.Last().Value2 = svalues[3];
                                                        else
                                                            throw new Exception("The URL for field filter 'Description' is invalid!");
                                                    }
                                                    break;
                                                case "exteriorcolor":
                                                    this.FieldFilters.Add(new FieldFilterExteriorColor() { Name = "ExteriorColor", Comparer = enumValue, ExteriorColor = svalues[2] });
                                                    if (enumValue == HP.Datastore.Common.ComparisonConstants.Between)
                                                    {
                                                        if (svalues.Length > 3)
                                                            this.FieldFilters.Last().Value2 = svalues[3];
                                                        else
                                                            throw new Exception("The URL for field filter 'ExteriorColor' is invalid!");
                                                    }
                                                    break;
                                                case "fueltype":
                                                    this.FieldFilters.Add(new FieldFilterFuelType() { Name = "FuelType", Comparer = enumValue, FuelType = svalues[2] });
                                                    if (enumValue == HP.Datastore.Common.ComparisonConstants.Between)
                                                    {
                                                        if (svalues.Length > 3)
                                                            this.FieldFilters.Last().Value2 = svalues[3];
                                                        else
                                                            throw new Exception("The URL for field filter 'FuelType' is invalid!");
                                                    }
                                                    break;
                                                case "interiorcolor":
                                                    this.FieldFilters.Add(new FieldFilterInteriorColor() { Name = "InteriorColor", Comparer = enumValue, InteriorColor = svalues[2] });
                                                    if (enumValue == HP.Datastore.Common.ComparisonConstants.Between)
                                                    {
                                                        if (svalues.Length > 3)
                                                            this.FieldFilters.Last().Value2 = svalues[3];
                                                        else
                                                            throw new Exception("The URL for field filter 'InteriorColor' is invalid!");
                                                    }
                                                    break;
                                                case "location":
                                                    double locationValue1, locationValue2, radius;
                                                    if (svalues.Length > 4)
                                                    {
                                                        if (double.TryParse(svalues[2], out locationValue1) && double.TryParse(svalues[3], out locationValue2) && double.TryParse(svalues[4], out radius))
                                                            this.FieldFilters.Add(new FieldFilterLocation() { Name = "Location", Comparer = enumValue, Latitude = locationValue1, Longitude = locationValue2, Radius = radius });
                                                        else
                                                            throw new Exception("The URL for field filter 'Location' is invalid!");
                                                    }
                                                    else
                                                        throw new Exception("The URL for field filter 'Location' is invalid!");
                                                    break;
                                                case "make":
                                                    this.FieldFilters.Add(new FieldFilterMake() { Name = "Make", Comparer = enumValue, Make = svalues[2] });
                                                    if (enumValue == HP.Datastore.Common.ComparisonConstants.Between)
                                                    {
                                                        if (svalues.Length > 3)
                                                            this.FieldFilters.Last().Value2 = svalues[3];
                                                        else
                                                            throw new Exception("The URL for field filter 'Make' is invalid!");
                                                    }
                                                    break;
                                                case "metro":
                                                    this.FieldFilters.Add(new FieldFilterMetro() { Name = "Metro", Comparer = enumValue, Metro = svalues[2] });
                                                    if (enumValue == HP.Datastore.Common.ComparisonConstants.Between)
                                                    {
                                                        if (svalues.Length > 3)
                                                            this.FieldFilters.Last().Value2 = svalues[3];
                                                        else
                                                            throw new Exception("The URL for field filter 'Metro' is invalid!");
                                                    }
                                                    break;
                                                case "mileage":
                                                    int mileageValue;
                                                    if (int.TryParse(svalues[2], out mileageValue))
                                                        this.FieldFilters.Add(new FieldFilterMileage() { Name = "Mileage", Comparer = enumValue, Mileage = mileageValue });
                                                    if (enumValue == HP.Datastore.Common.ComparisonConstants.Between)
                                                    {
                                                        if (svalues.Length > 3)
                                                        {
                                                            if (int.TryParse(svalues[3], out mileageValue))
                                                                this.FieldFilters.Last().Value2 = mileageValue;
                                                            else
                                                                throw new Exception("The URL for field filter 'Mileage' is invalid!");
                                                        }
                                                        else
                                                            throw new Exception("The URL for field filter 'Mileage' is invalid!");
                                                    }
                                                    break;
                                                case "model":
                                                    this.FieldFilters.Add(new FieldFilterModel() { Name = "Model", Comparer = enumValue, Model = svalues[2] });
                                                    if (enumValue == HP.Datastore.Common.ComparisonConstants.Between)
                                                    {
                                                        if (svalues.Length > 3)
                                                            this.FieldFilters.Last().Value2 = svalues[3];
                                                        else
                                                            throw new Exception("The URL for field filter 'Model' is invalid!");
                                                    }
                                                    break;
                                                case "postdate":
                                                    DateTime postdateValue;
                                                    if (DateTime.TryParse(svalues[2], out postdateValue))
                                                        this.FieldFilters.Add(new FieldFilterPostDate() { Name = "PostDate", Comparer = enumValue, PostDate = postdateValue });
                                                    if (enumValue == HP.Datastore.Common.ComparisonConstants.Between)
                                                    {
                                                        if (svalues.Length > 3)
                                                        {
                                                            if (DateTime.TryParse(svalues[3], out postdateValue))
                                                                this.FieldFilters.Last().Value2 = postdateValue;
                                                            else
                                                                throw new Exception("The URL for field filter 'PostDate' is invalid!");
                                                        }
                                                        else
                                                            throw new Exception("The URL for field filter 'PostDate' is invalid!");
                                                    }
                                                    break;
                                                case "price":
                                                    int priceValue;
                                                    if (int.TryParse(svalues[2], out priceValue))
                                                        this.FieldFilters.Add(new FieldFilterPrice() { Name = "Price", Comparer = enumValue, Price = priceValue });
                                                    if (enumValue == HP.Datastore.Common.ComparisonConstants.Between)
                                                    {
                                                        if (svalues.Length > 3)
                                                        {
                                                            if (int.TryParse(svalues[3], out priceValue))
                                                                this.FieldFilters.Last().Value2 = priceValue;
                                                            else
                                                                throw new Exception("The URL for field filter 'Price' is invalid!");
                                                        }
                                                        else
                                                            throw new Exception("The URL for field filter 'Price' is invalid!");
                                                    }
                                                    break;
                                                case "state":
                                                    this.FieldFilters.Add(new FieldFilterState() { Name = "State", Comparer = enumValue, State = svalues[2] });
                                                    if (enumValue == HP.Datastore.Common.ComparisonConstants.Between)
                                                    {
                                                        if (svalues.Length > 3)
                                                            this.FieldFilters.Last().Value2 = svalues[3];
                                                        else
                                                            throw new Exception("The URL for field filter 'State' is invalid!");
                                                    }
                                                    break;
                                                case "title":
                                                    this.FieldFilters.Add(new FieldFilterTitle() { Name = "Title", Comparer = enumValue, Title = svalues[2] });
                                                    if (enumValue == HP.Datastore.Common.ComparisonConstants.Between)
                                                    {
                                                        if (svalues.Length > 3)
                                                            this.FieldFilters.Last().Value2 = svalues[3];
                                                        else
                                                            throw new Exception("The URL for field filter 'Title' is invalid!");
                                                    }
                                                    break;
                                                case "transmission":
                                                    this.FieldFilters.Add(new FieldFilterTransmission() { Name = "Transmission", Comparer = enumValue, Transmission = svalues[2] });
                                                    if (enumValue == HP.Datastore.Common.ComparisonConstants.Between)
                                                    {
                                                        if (svalues.Length > 3)
                                                            this.FieldFilters.Last().Value2 = svalues[3];
                                                        else
                                                            throw new Exception("The URL for field filter 'Transmission' is invalid!");
                                                    }
                                                    break;
                                                case "userid":
                                                    int useridValue;
                                                    if (int.TryParse(svalues[2], out useridValue))
                                                        this.FieldFilters.Add(new FieldFilterUserId() { Name = "UserId", Comparer = enumValue, UserId = useridValue });
                                                    if (enumValue == HP.Datastore.Common.ComparisonConstants.Between)
                                                    {
                                                        if (svalues.Length > 3)
                                                        {
                                                            if (int.TryParse(svalues[3], out useridValue))
                                                                this.FieldFilters.Last().Value2 = useridValue;
                                                            else
                                                                throw new Exception("The URL for field filter 'UserId' is invalid!");
                                                        }
                                                        else
                                                            throw new Exception("The URL for field filter 'UserId' is invalid!");
                                                    }
                                                    break;
                                                case "vin":
                                                    this.FieldFilters.Add(new FieldFilterVIN() { Name = "VIN", Comparer = enumValue, VIN = svalues[2] });
                                                    if (enumValue == HP.Datastore.Common.ComparisonConstants.Between)
                                                    {
                                                        if (svalues.Length > 3)
                                                            this.FieldFilters.Last().Value2 = svalues[3];
                                                        else
                                                            throw new Exception("The URL for field filter 'VIN' is invalid!");
                                                    }
                                                    break;
                                                case "year":
                                                    int yearValue;
                                                    if (int.TryParse(svalues[2], out yearValue))
                                                        this.FieldFilters.Add(new FieldFilterYear() { Name = "Year", Comparer = enumValue, Year = yearValue });
                                                    if (enumValue == HP.Datastore.Common.ComparisonConstants.Between)
                                                    {
                                                        if (svalues.Length > 3)
                                                        {
                                                            if (int.TryParse(svalues[3], out yearValue))
                                                                this.FieldFilters.Last().Value2 = yearValue;
                                                            else
                                                                throw new Exception("The URL for field filter 'Year' is invalid!");
                                                        }
                                                        else
                                                            throw new Exception("The URL for field filter 'Year' is invalid!");
                                                    }
                                                    break;
                                                case "zip":
                                                    this.FieldFilters.Add(new FieldFilterZIP() { Name = "ZIP", Comparer = enumValue, ZIP = svalues[2] });
                                                    if (enumValue == HP.Datastore.Common.ComparisonConstants.Between)
                                                    {
                                                        if (svalues.Length > 3)
                                                            this.FieldFilters.Last().Value2 = svalues[3];
                                                        else
                                                            throw new Exception("The URL for field filter 'ZIP' is invalid!");
                                                    }
                                                    break;
                                            }
                                        }
                                    }
                                }
                            }
                            break;
                            #endregion
                        case "fs":
                            #region Search
                            {
                                var sorts = values[1].Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
                                foreach (var s in sorts)
                                {
                                    var svalues = s.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                                    if (svalues.Length > 0)
                                    {
                                        switch (svalues[0].ToLower())
                                        {
                                            case "autoid":
                                                this.FieldSorts.Add(new FieldSortAutoID() { Name = "AutoID", SortDirection = (svalues.Length == 1 || svalues[1] != "0" ? HP.Datastore.Common.SortDirectionConstants.Asc : HP.Datastore.Common.SortDirectionConstants.Desc) });
                                                break;
                                            case "bodytype":
                                                this.FieldSorts.Add(new FieldSortBodyType() { Name = "BodyType", SortDirection = (svalues.Length == 1 || svalues[1] != "0" ? HP.Datastore.Common.SortDirectionConstants.Asc : HP.Datastore.Common.SortDirectionConstants.Desc) });
                                                break;
                                            case "city":
                                                this.FieldSorts.Add(new FieldSortCity() { Name = "City", SortDirection = (svalues.Length == 1 || svalues[1] != "0" ? HP.Datastore.Common.SortDirectionConstants.Asc : HP.Datastore.Common.SortDirectionConstants.Desc) });
                                                break;
                                            case "condition":
                                                this.FieldSorts.Add(new FieldSortCondition() { Name = "Condition", SortDirection = (svalues.Length == 1 || svalues[1] != "0" ? HP.Datastore.Common.SortDirectionConstants.Asc : HP.Datastore.Common.SortDirectionConstants.Desc) });
                                                break;
                                            case "dealer":
                                                this.FieldSorts.Add(new FieldSortDealer() { Name = "Dealer", SortDirection = (svalues.Length == 1 || svalues[1] != "0" ? HP.Datastore.Common.SortDirectionConstants.Asc : HP.Datastore.Common.SortDirectionConstants.Desc) });
                                                break;
                                            case "description":
                                                this.FieldSorts.Add(new FieldSortDescription() { Name = "Description", SortDirection = (svalues.Length == 1 || svalues[1] != "0" ? HP.Datastore.Common.SortDirectionConstants.Asc : HP.Datastore.Common.SortDirectionConstants.Desc) });
                                                break;
                                            case "exteriorcolor":
                                                this.FieldSorts.Add(new FieldSortExteriorColor() { Name = "ExteriorColor", SortDirection = (svalues.Length == 1 || svalues[1] != "0" ? HP.Datastore.Common.SortDirectionConstants.Asc : HP.Datastore.Common.SortDirectionConstants.Desc) });
                                                break;
                                            case "fueltype":
                                                this.FieldSorts.Add(new FieldSortFuelType() { Name = "FuelType", SortDirection = (svalues.Length == 1 || svalues[1] != "0" ? HP.Datastore.Common.SortDirectionConstants.Asc : HP.Datastore.Common.SortDirectionConstants.Desc) });
                                                break;
                                            case "interiorcolor":
                                                this.FieldSorts.Add(new FieldSortInteriorColor() { Name = "InteriorColor", SortDirection = (svalues.Length == 1 || svalues[1] != "0" ? HP.Datastore.Common.SortDirectionConstants.Asc : HP.Datastore.Common.SortDirectionConstants.Desc) });
                                                break;
                                            case "make":
                                                this.FieldSorts.Add(new FieldSortMake() { Name = "Make", SortDirection = (svalues.Length == 1 || svalues[1] != "0" ? HP.Datastore.Common.SortDirectionConstants.Asc : HP.Datastore.Common.SortDirectionConstants.Desc) });
                                                break;
                                            case "metro":
                                                this.FieldSorts.Add(new FieldSortMetro() { Name = "Metro", SortDirection = (svalues.Length == 1 || svalues[1] != "0" ? HP.Datastore.Common.SortDirectionConstants.Asc : HP.Datastore.Common.SortDirectionConstants.Desc) });
                                                break;
                                            case "mileage":
                                                this.FieldSorts.Add(new FieldSortMileage() { Name = "Mileage", SortDirection = (svalues.Length == 1 || svalues[1] != "0" ? HP.Datastore.Common.SortDirectionConstants.Asc : HP.Datastore.Common.SortDirectionConstants.Desc) });
                                                break;
                                            case "model":
                                                this.FieldSorts.Add(new FieldSortModel() { Name = "Model", SortDirection = (svalues.Length == 1 || svalues[1] != "0" ? HP.Datastore.Common.SortDirectionConstants.Asc : HP.Datastore.Common.SortDirectionConstants.Desc) });
                                                break;
                                            case "postdate":
                                                this.FieldSorts.Add(new FieldSortPostDate() { Name = "PostDate", SortDirection = (svalues.Length == 1 || svalues[1] != "0" ? HP.Datastore.Common.SortDirectionConstants.Asc : HP.Datastore.Common.SortDirectionConstants.Desc) });
                                                break;
                                            case "price":
                                                this.FieldSorts.Add(new FieldSortPrice() { Name = "Price", SortDirection = (svalues.Length == 1 || svalues[1] != "0" ? HP.Datastore.Common.SortDirectionConstants.Asc : HP.Datastore.Common.SortDirectionConstants.Desc) });
                                                break;
                                            case "state":
                                                this.FieldSorts.Add(new FieldSortState() { Name = "State", SortDirection = (svalues.Length == 1 || svalues[1] != "0" ? HP.Datastore.Common.SortDirectionConstants.Asc : HP.Datastore.Common.SortDirectionConstants.Desc) });
                                                break;
                                            case "title":
                                                this.FieldSorts.Add(new FieldSortTitle() { Name = "Title", SortDirection = (svalues.Length == 1 || svalues[1] != "0" ? HP.Datastore.Common.SortDirectionConstants.Asc : HP.Datastore.Common.SortDirectionConstants.Desc) });
                                                break;
                                            case "transmission":
                                                this.FieldSorts.Add(new FieldSortTransmission() { Name = "Transmission", SortDirection = (svalues.Length == 1 || svalues[1] != "0" ? HP.Datastore.Common.SortDirectionConstants.Asc : HP.Datastore.Common.SortDirectionConstants.Desc) });
                                                break;
                                            case "userid":
                                                this.FieldSorts.Add(new FieldSortUserId() { Name = "UserId", SortDirection = (svalues.Length == 1 || svalues[1] != "0" ? HP.Datastore.Common.SortDirectionConstants.Asc : HP.Datastore.Common.SortDirectionConstants.Desc) });
                                                break;
                                            case "vin":
                                                this.FieldSorts.Add(new FieldSortVIN() { Name = "VIN", SortDirection = (svalues.Length == 1 || svalues[1] != "0" ? HP.Datastore.Common.SortDirectionConstants.Asc : HP.Datastore.Common.SortDirectionConstants.Desc) });
                                                break;
                                            case "year":
                                                this.FieldSorts.Add(new FieldSortYear() { Name = "Year", SortDirection = (svalues.Length == 1 || svalues[1] != "0" ? HP.Datastore.Common.SortDirectionConstants.Asc : HP.Datastore.Common.SortDirectionConstants.Desc) });
                                                break;
                                            case "zip":
                                                this.FieldSorts.Add(new FieldSortZIP() { Name = "ZIP", SortDirection = (svalues.Length == 1 || svalues[1] != "0" ? HP.Datastore.Common.SortDirectionConstants.Asc : HP.Datastore.Common.SortDirectionConstants.Desc) });
                                                break;
                                        }
                                    }
                                }
                            }
                            break;
                            #endregion
                        case "srch":
                            this.Keyword = values[1];
                            break;
                        default:
                            if (values.Length >= 2)
                            {
                                if (this.NonParsedFieldList.Count(x => x.Key == values[0]) > 0)
                                    this.NonParsedFieldList.First(x => x.Key == values[0]).Value = values[1];
                                else
                                    this.NonParsedFieldList.Add(new NamedItem() { Key = values[0], Value = values[1] });
                            }
                            break;
                    }
                }
            }
            #endregion

            var eventParam = new HP.Datastore.Common.EventArguments.BeforeValueEventArgs<string>() { Value = originalUrl };
            this.OnAfterLoadFromUrlComplete(eventParam);

        }

        public static HP.Datastore.Common.FieldSort GetSortByName(ListingItem.FieldConstants field)
        {
            return GetSortByName(field.ToString());
        }

        public static HP.Datastore.Common.FieldSort GetSortByName(string name)
        {
            if (name.ToLower() == "AutoID".ToLower()) return new FieldSortAutoID() { Name = "AutoID", SortDirection = HP.Datastore.Common.SortDirectionConstants.Asc };
            if (name.ToLower() == "Make".ToLower()) return new FieldSortMake() { Name = "Make", SortDirection = HP.Datastore.Common.SortDirectionConstants.Asc };
            if (name.ToLower() == "Model".ToLower()) return new FieldSortModel() { Name = "Model", SortDirection = HP.Datastore.Common.SortDirectionConstants.Asc };
            if (name.ToLower() == "State".ToLower()) return new FieldSortState() { Name = "State", SortDirection = HP.Datastore.Common.SortDirectionConstants.Asc };
            if (name.ToLower() == "ExteriorColor".ToLower()) return new FieldSortExteriorColor() { Name = "ExteriorColor", SortDirection = HP.Datastore.Common.SortDirectionConstants.Asc };
            if (name.ToLower() == "InteriorColor".ToLower()) return new FieldSortInteriorColor() { Name = "InteriorColor", SortDirection = HP.Datastore.Common.SortDirectionConstants.Asc };
            if (name.ToLower() == "Condition".ToLower()) return new FieldSortCondition() { Name = "Condition", SortDirection = HP.Datastore.Common.SortDirectionConstants.Asc };
            if (name.ToLower() == "Mileage".ToLower()) return new FieldSortMileage() { Name = "Mileage", SortDirection = HP.Datastore.Common.SortDirectionConstants.Asc };
            if (name.ToLower() == "Price".ToLower()) return new FieldSortPrice() { Name = "Price", SortDirection = HP.Datastore.Common.SortDirectionConstants.Asc };
            if (name.ToLower() == "Transmission".ToLower()) return new FieldSortTransmission() { Name = "Transmission", SortDirection = HP.Datastore.Common.SortDirectionConstants.Asc };
            if (name.ToLower() == "Year".ToLower()) return new FieldSortYear() { Name = "Year", SortDirection = HP.Datastore.Common.SortDirectionConstants.Asc };
            if (name.ToLower() == "City".ToLower()) return new FieldSortCity() { Name = "City", SortDirection = HP.Datastore.Common.SortDirectionConstants.Asc };
            if (name.ToLower() == "Metro".ToLower()) return new FieldSortMetro() { Name = "Metro", SortDirection = HP.Datastore.Common.SortDirectionConstants.Asc };
            if (name.ToLower() == "PostDate".ToLower()) return new FieldSortPostDate() { Name = "PostDate", SortDirection = HP.Datastore.Common.SortDirectionConstants.Asc };
            if (name.ToLower() == "ZIP".ToLower()) return new FieldSortZIP() { Name = "ZIP", SortDirection = HP.Datastore.Common.SortDirectionConstants.Asc };
            if (name.ToLower() == "VIN".ToLower()) return new FieldSortVIN() { Name = "VIN", SortDirection = HP.Datastore.Common.SortDirectionConstants.Asc };
            if (name.ToLower() == "UserId".ToLower()) return new FieldSortUserId() { Name = "UserId", SortDirection = HP.Datastore.Common.SortDirectionConstants.Asc };
            if (name.ToLower() == "Title".ToLower()) return new FieldSortTitle() { Name = "Title", SortDirection = HP.Datastore.Common.SortDirectionConstants.Asc };
            if (name.ToLower() == "FuelType".ToLower()) return new FieldSortFuelType() { Name = "FuelType", SortDirection = HP.Datastore.Common.SortDirectionConstants.Asc };
            if (name.ToLower() == "Description".ToLower()) return new FieldSortDescription() { Name = "Description", SortDirection = HP.Datastore.Common.SortDirectionConstants.Asc };
            if (name.ToLower() == "Dealer".ToLower()) return new FieldSortDealer() { Name = "Dealer", SortDirection = HP.Datastore.Common.SortDirectionConstants.Asc };
            if (name.ToLower() == "BodyType".ToLower()) return new FieldSortBodyType() { Name = "BodyType", SortDirection = HP.Datastore.Common.SortDirectionConstants.Asc };
            return null;
        }

        public void OrderBy(ListingItem.FieldConstants sort)
        {
            var o = ListingQuery.GetSortByName(sort.ToString());
            if (o == null) return;
            this.FieldSorts.Add(o);
        }

        public void OrderBy(string sort)
        {
            var o = ListingQuery.GetSortByName(sort);
            if (o == null) return;
            this.FieldSorts.Add(o);
        }

        public void OrderByDescending(ListingItem.FieldConstants sort)
        {
            var o = ListingQuery.GetSortByName(sort.ToString());
            if (o == null) return;
            o.SortDirection = HP.Datastore.Common.SortDirectionConstants.Desc;
            this.FieldSorts.Add(o);
        }

        public void OrderByDescending(string sort)
        {
            var o = ListingQuery.GetSortByName(sort);
            if (o == null) return;
            o.SortDirection = HP.Datastore.Common.SortDirectionConstants.Desc;
            this.FieldSorts.Add(o);
        }

        public HP.Datastore.Common.DataQuery ToTransfer()
        {
            var retval = new HP.Datastore.Common.DataQuery();
            retval.DimensionValueList = this.DimensionValueList;
            retval.Credentials = this.Credentials;
            retval.IPMask = this.IPMask;
            retval.IncludeDimensions = this.IncludeDimensions;
            retval.IncludeEmptyDimensions = this.IncludeEmptyDimensions;
            retval.IncludeRecords = this.IncludeRecords;
            if (this.DerivedFieldList != null)
            {
                var aggList = new List<IDerivedField>();
                foreach (var item in this.DerivedFieldList)
                {
                    var newItem = item as DerivedField;
                    if (newItem == null)
                    {
                        newItem = new DerivedField { Action = item.Action };
                        switch (((ListingDerivedField)item).Field)
                        {
                            case ListingItem.FieldConstants.AutoID: newItem.Field = "AutoID"; break;
                            case ListingItem.FieldConstants.Make: newItem.Field = "Make"; break;
                            case ListingItem.FieldConstants.Model: newItem.Field = "Model"; break;
                            case ListingItem.FieldConstants.State: newItem.Field = "State"; break;
                            case ListingItem.FieldConstants.ExteriorColor: newItem.Field = "ExteriorColor"; break;
                            case ListingItem.FieldConstants.InteriorColor: newItem.Field = "InteriorColor"; break;
                            case ListingItem.FieldConstants.Condition: newItem.Field = "Condition"; break;
                            case ListingItem.FieldConstants.Mileage: newItem.Field = "Mileage"; break;
                            case ListingItem.FieldConstants.Price: newItem.Field = "Price"; break;
                            case ListingItem.FieldConstants.Transmission: newItem.Field = "Transmission"; break;
                            case ListingItem.FieldConstants.Year: newItem.Field = "Year"; break;
                            case ListingItem.FieldConstants.City: newItem.Field = "City"; break;
                            case ListingItem.FieldConstants.Location: newItem.Field = "Location"; break;
                            case ListingItem.FieldConstants.Metro: newItem.Field = "Metro"; break;
                            case ListingItem.FieldConstants.PostDate: newItem.Field = "PostDate"; break;
                            case ListingItem.FieldConstants.ZIP: newItem.Field = "ZIP"; break;
                            case ListingItem.FieldConstants.VIN: newItem.Field = "VIN"; break;
                            case ListingItem.FieldConstants.UserId: newItem.Field = "UserId"; break;
                            case ListingItem.FieldConstants.Title: newItem.Field = "Title"; break;
                            case ListingItem.FieldConstants.FuelType: newItem.Field = "FuelType"; break;
                            case ListingItem.FieldConstants.Description: newItem.Field = "Description"; break;
                            case ListingItem.FieldConstants.Dealer: newItem.Field = "Dealer"; break;
                            case ListingItem.FieldConstants.BodyType: newItem.Field = "BodyType"; break;
                        }
                    }
                    aggList.Add(newItem);
                }
                retval.DerivedFieldList = aggList;
            }

            retval.FieldFilters = new List<HP.Datastore.Common.IFieldFilter>();
            if (this.FieldFilters == null)
                this.FieldFilters = new List<IFieldFilter>();
            foreach (var o in this.FieldFilters)
            {
                if (o is HP.Datastore.Common.GeoCodeFieldFilter)
                {
                    var newFilter = new HP.Datastore.Common.GeoCodeFieldFilter()
                    {
                        Latitude = ((HP.Datastore.Common.GeoCodeFieldFilter)o).Latitude,
                        Longitude = ((HP.Datastore.Common.GeoCodeFieldFilter)o).Longitude,
                        Radius = ((HP.Datastore.Common.GeoCodeFieldFilter)o).Radius,
                        Comparer = o.Comparer,
                        Name = o.Name,
                    };
                    ((HP.Datastore.Common.IFieldFilter)newFilter).Value = ((HP.Datastore.Common.IFieldFilter)o).Value;
                    ((HP.Datastore.Common.IFieldFilter)newFilter).Value2 = ((HP.Datastore.Common.IFieldFilter)o).Value2;
                    retval.FieldFilters.Add(newFilter);
                }
                else
                {
                    var newFilter = new HP.Datastore.Common.FieldFilter()
                    {
                        Comparer = o.Comparer,
                        Name = o.Name,
                    };
                    ((HP.Datastore.Common.IFieldFilter)newFilter).Value = ((HP.Datastore.Common.IFieldFilter)o).Value;
                    ((HP.Datastore.Common.IFieldFilter)newFilter).Value2 = ((HP.Datastore.Common.IFieldFilter)o).Value2;
                    retval.FieldFilters.Add(newFilter);
                }
            }

            retval.FieldSorts = new List<HP.Datastore.Common.IFieldSort>();
            if (this.FieldSorts == null)
                this.FieldSorts = new List<IFieldSort>();
            foreach (var o in this.FieldSorts)
            {
                retval.FieldSorts.Add(new HP.Datastore.Common.FieldSort()
                {
                    Name = o.Name,
                    SortDirection = o.SortDirection,
                });
            }

            if (this.NonParsedFieldList != null)
            {
                this.NonParsedFieldList.ForEach(x => retval.NonParsedFieldList.Add(x));
            }

            retval.Keyword = this.Keyword;
            retval.PageOffset = this.PageOffset;
            retval.RecordsPerPage = this.RecordsPerPage;
            return retval;
        }

        public override string ToString()
        {
            var retval = string.Empty;

            #region Dimensions
            if (this.DimensionValueList != null && this.DimensionValueList.Count > 0)
            {
                retval += "d=" + string.Join("+", this.DimensionValueList.Select(x => x.ToString()));
            }
            #endregion

            #region Field Filters
            if (this.FieldFilters != null && this.FieldFilters.Count > 0)
            {
                var ffURL = string.Empty;
                foreach (var ff in this.FieldFilters)
                {
                    var fieldName = string.Empty;
                    if (1 == 0) ;
                    else if (ff is FieldFilterAutoID) fieldName = "AutoID";
                    else if (ff is FieldFilterBodyType) fieldName = "BodyType";
                    else if (ff is FieldFilterCity) fieldName = "City";
                    else if (ff is FieldFilterCondition) fieldName = "Condition";
                    else if (ff is FieldFilterDealer) fieldName = "Dealer";
                    else if (ff is FieldFilterDescription) fieldName = "Description";
                    else if (ff is FieldFilterExteriorColor) fieldName = "ExteriorColor";
                    else if (ff is FieldFilterFuelType) fieldName = "FuelType";
                    else if (ff is FieldFilterInteriorColor) fieldName = "InteriorColor";
                    else if (ff is FieldFilterLocation) fieldName = "Location";
                    else if (ff is FieldFilterMake) fieldName = "Make";
                    else if (ff is FieldFilterMetro) fieldName = "Metro";
                    else if (ff is FieldFilterMileage) fieldName = "Mileage";
                    else if (ff is FieldFilterModel) fieldName = "Model";
                    else if (ff is FieldFilterPostDate) fieldName = "PostDate";
                    else if (ff is FieldFilterPrice) fieldName = "Price";
                    else if (ff is FieldFilterState) fieldName = "State";
                    else if (ff is FieldFilterTitle) fieldName = "Title";
                    else if (ff is FieldFilterTransmission) fieldName = "Transmission";
                    else if (ff is FieldFilterUserId) fieldName = "UserId";
                    else if (ff is FieldFilterVIN) fieldName = "VIN";
                    else if (ff is FieldFilterYear) fieldName = "Year";
                    else if (ff is FieldFilterZIP) fieldName = "ZIP";
                    else throw new Exception("The filter type is not valid!");

                    var f1 = (HP.Datastore.Common.IFieldFilter)ff;
                    if (ff is HP.Datastore.Common.GeoCodeFieldFilter)
                    {
                        var gff = ff as HP.Datastore.Common.GeoCodeFieldFilter;
                        if (gff != null)
                            ffURL += fieldName + "," + ff.Comparer.ToString() + "," + gff.Latitude.ToString() + "," + gff.Longitude.ToString() + "," + gff.Radius.ToString() + "|";
                    }
                    else
                    {
                        if (ff.Comparer == HP.Datastore.Common.ComparisonConstants.Between)
                        {
                            if ((f1.Value != null) && (f1.Value2 != null))
                            {
                                ffURL += fieldName + "," + ff.Comparer.ToString() + "," + f1.Value.ToString() + "," + f1.Value2.ToString() + "|";
                            }
                        }
                        else
                        {
                            if (f1.Value != null)
                            {
                                ffURL += fieldName + "," + ff.Comparer.ToString() + "," + f1.Value.ToString() + "|";
                            }
                        }
                    }
                }

                ffURL = ffURL.Trim('|');
                if (!string.IsNullOrEmpty(ffURL))
                    retval += "&ff=" + ffURL;
            }
            #endregion

            #region Field Sorts
            if (this.FieldSorts != null && this.FieldSorts.Count > 0)
            {
                var fsURL = string.Empty;
                foreach (var fs in this.FieldSorts)
                {
                    if (1 == 0) ;
                    else if (fs is FieldSortAutoID) fsURL += "AutoID";
                    else if (fs is FieldSortBodyType) fsURL += "BodyType";
                    else if (fs is FieldSortCity) fsURL += "City";
                    else if (fs is FieldSortCondition) fsURL += "Condition";
                    else if (fs is FieldSortDealer) fsURL += "Dealer";
                    else if (fs is FieldSortDescription) fsURL += "Description";
                    else if (fs is FieldSortExteriorColor) fsURL += "ExteriorColor";
                    else if (fs is FieldSortFuelType) fsURL += "FuelType";
                    else if (fs is FieldSortInteriorColor) fsURL += "InteriorColor";
                    else if (fs is FieldSortMake) fsURL += "Make";
                    else if (fs is FieldSortMetro) fsURL += "Metro";
                    else if (fs is FieldSortMileage) fsURL += "Mileage";
                    else if (fs is FieldSortModel) fsURL += "Model";
                    else if (fs is FieldSortPostDate) fsURL += "PostDate";
                    else if (fs is FieldSortPrice) fsURL += "Price";
                    else if (fs is FieldSortState) fsURL += "State";
                    else if (fs is FieldSortTitle) fsURL += "Title";
                    else if (fs is FieldSortTransmission) fsURL += "Transmission";
                    else if (fs is FieldSortUserId) fsURL += "UserId";
                    else if (fs is FieldSortVIN) fsURL += "VIN";
                    else if (fs is FieldSortYear) fsURL += "Year";
                    else if (fs is FieldSortZIP) fsURL += "ZIP";
                    else throw new Exception("The sort type is not valid!");
                    fsURL += (fs.SortDirection == HP.Datastore.Common.SortDirectionConstants.Asc ? string.Empty : ",0");
                }

                fsURL = fsURL.Trim('|');
                if (!string.IsNullOrEmpty(fsURL))
                    retval += "&fs=" + fsURL;
            }
            #endregion

            #region Keyword
            if (!string.IsNullOrEmpty(this.Keyword))
            {
                retval += "&srch=" + this.Keyword;
            }
            #endregion

            if (this.PageOffset != 1 || this.UseDefaults)
                retval += "&po=" + this.PageOffset;
            if (this.RecordsPerPage != 10 || this.UseDefaults)
                retval += "&rpp=" + this.RecordsPerPage;

            #region NonParsed Field
            if (this.NonParsedFieldList != null)
            {
                foreach (var item in this.NonParsedFieldList.Where(x => !string.IsNullOrEmpty(x.Value)))
                {
                    retval += "&" + item.Key + "=" + item.Value;
                }
            }
            #endregion

            retval = retval.Trim('&');

            if (string.IsNullOrEmpty(this.PageName))
                return retval;
            else if (!string.IsNullOrEmpty(retval))
                return this.PageName + "?" + retval;
            else
                return this.PageName;
            if (string.IsNullOrEmpty(this.PageName))
            {
                //Do Nothing
            }
            else if (!string.IsNullOrEmpty(retval))
            {
                retval = this.PageName + "?" + retval;
            }
            else
            {
                retval = this.PageName;
            }

            var eventParam = new HP.Datastore.Common.EventArguments.BeforeValueEventArgs<string>() { Value = retval };
            this.OnAfterPostToString(eventParam);
            retval = eventParam.Value;

            return retval;
        }

        partial void Cloning(ListingQuery query);

        object ICloneable.Clone()
        {
            return this.Clone();
        }

        public ListingQuery Clone()
        {
            var retval = new ListingQuery();
            retval.DimensionValueList.AddRange(this.DimensionValueList);
            retval.FieldFilters.AddRange(this.FieldFilters);
            retval.FieldSorts.AddRange(this.FieldSorts);
            retval.Keyword = this.Keyword;
            retval.NonParsedFieldList.AddRange(this.NonParsedFieldList);
            retval.PageOffset = this.PageOffset;
            retval.PageName = this.PageName;
            retval.RecordsPerPage = this.RecordsPerPage;
            retval.IncludeDimensions = this.IncludeDimensions;
            retval.IncludeEmptyDimensions = this.IncludeEmptyDimensions;
            retval.IncludeRecords = this.IncludeRecords;
            if (this.DerivedFieldList != null)
            {
                var aggList = new List<IDerivedField>();
                foreach (var item in this.DerivedFieldList)
                {
                    var newItem = item as DerivedField;
                    if (newItem == null)
                    {
                        newItem = new DerivedField { Action = item.Action };
                        switch (((ListingDerivedField)item).Field)
                        {
                            case ListingItem.FieldConstants.AutoID: newItem.Field = "AutoID"; break;
                            case ListingItem.FieldConstants.Make: newItem.Field = "Make"; break;
                            case ListingItem.FieldConstants.Model: newItem.Field = "Model"; break;
                            case ListingItem.FieldConstants.State: newItem.Field = "State"; break;
                            case ListingItem.FieldConstants.ExteriorColor: newItem.Field = "ExteriorColor"; break;
                            case ListingItem.FieldConstants.InteriorColor: newItem.Field = "InteriorColor"; break;
                            case ListingItem.FieldConstants.Condition: newItem.Field = "Condition"; break;
                            case ListingItem.FieldConstants.Mileage: newItem.Field = "Mileage"; break;
                            case ListingItem.FieldConstants.Price: newItem.Field = "Price"; break;
                            case ListingItem.FieldConstants.Transmission: newItem.Field = "Transmission"; break;
                            case ListingItem.FieldConstants.Year: newItem.Field = "Year"; break;
                            case ListingItem.FieldConstants.City: newItem.Field = "City"; break;
                            case ListingItem.FieldConstants.Location: newItem.Field = "Location"; break;
                            case ListingItem.FieldConstants.Metro: newItem.Field = "Metro"; break;
                            case ListingItem.FieldConstants.PostDate: newItem.Field = "PostDate"; break;
                            case ListingItem.FieldConstants.ZIP: newItem.Field = "ZIP"; break;
                            case ListingItem.FieldConstants.VIN: newItem.Field = "VIN"; break;
                            case ListingItem.FieldConstants.UserId: newItem.Field = "UserId"; break;
                            case ListingItem.FieldConstants.Title: newItem.Field = "Title"; break;
                            case ListingItem.FieldConstants.FuelType: newItem.Field = "FuelType"; break;
                            case ListingItem.FieldConstants.Description: newItem.Field = "Description"; break;
                            case ListingItem.FieldConstants.Dealer: newItem.Field = "Dealer"; break;
                            case ListingItem.FieldConstants.BodyType: newItem.Field = "BodyType"; break;
                        }
                    }
                    aggList.Add(newItem);
                }
                retval.DerivedFieldList = aggList;
            }
            this.Cloning(retval);
            return retval;
        }

    }

    #region Filtering

    [Serializable]
    public sealed class FieldFilterAutoID : HP.Datastore.Common.FieldFilter, HP.Datastore.Common.IFieldFilter
    {
        public FieldFilterAutoID() : base("AutoID") { }
        public int? AutoID { get; set; }
        object HP.Datastore.Common.IFieldFilter.Value
        {
            get { return this.AutoID; }
            set { this.AutoID = (int?)value; }
        }
    }

    [Serializable]
    public sealed class FieldFilterMake : HP.Datastore.Common.FieldFilter, HP.Datastore.Common.IFieldFilter
    {
        public FieldFilterMake() : base("Make") { }
        public string Make { get; set; }
        object HP.Datastore.Common.IFieldFilter.Value
        {
            get { return this.Make; }
            set { this.Make = (string)value; }
        }
    }

    [Serializable]
    public sealed class FieldFilterModel : HP.Datastore.Common.FieldFilter, HP.Datastore.Common.IFieldFilter
    {
        public FieldFilterModel() : base("Model") { }
        public string Model { get; set; }
        object HP.Datastore.Common.IFieldFilter.Value
        {
            get { return this.Model; }
            set { this.Model = (string)value; }
        }
    }

    [Serializable]
    public sealed class FieldFilterState : HP.Datastore.Common.FieldFilter, HP.Datastore.Common.IFieldFilter
    {
        public FieldFilterState() : base("State") { }
        public string State { get; set; }
        object HP.Datastore.Common.IFieldFilter.Value
        {
            get { return this.State; }
            set { this.State = (string)value; }
        }
    }

    [Serializable]
    public sealed class FieldFilterExteriorColor : HP.Datastore.Common.FieldFilter, HP.Datastore.Common.IFieldFilter
    {
        public FieldFilterExteriorColor() : base("ExteriorColor") { }
        public string ExteriorColor { get; set; }
        object HP.Datastore.Common.IFieldFilter.Value
        {
            get { return this.ExteriorColor; }
            set { this.ExteriorColor = (string)value; }
        }
    }

    [Serializable]
    public sealed class FieldFilterInteriorColor : HP.Datastore.Common.FieldFilter, HP.Datastore.Common.IFieldFilter
    {
        public FieldFilterInteriorColor() : base("InteriorColor") { }
        public string InteriorColor { get; set; }
        object HP.Datastore.Common.IFieldFilter.Value
        {
            get { return this.InteriorColor; }
            set { this.InteriorColor = (string)value; }
        }
    }

    [Serializable]
    public sealed class FieldFilterCondition : HP.Datastore.Common.FieldFilter, HP.Datastore.Common.IFieldFilter
    {
        public FieldFilterCondition() : base("Condition") { }
        public string Condition { get; set; }
        object HP.Datastore.Common.IFieldFilter.Value
        {
            get { return this.Condition; }
            set { this.Condition = (string)value; }
        }
    }

    [Serializable]
    public sealed class FieldFilterMileage : HP.Datastore.Common.FieldFilter, HP.Datastore.Common.IFieldFilter
    {
        public FieldFilterMileage() : base("Mileage") { }
        public int? Mileage { get; set; }
        object HP.Datastore.Common.IFieldFilter.Value
        {
            get { return this.Mileage; }
            set { this.Mileage = (int?)value; }
        }
    }

    [Serializable]
    public sealed class FieldFilterPrice : HP.Datastore.Common.FieldFilter, HP.Datastore.Common.IFieldFilter
    {
        public FieldFilterPrice() : base("Price") { }
        public int? Price { get; set; }
        object HP.Datastore.Common.IFieldFilter.Value
        {
            get { return this.Price; }
            set { this.Price = (int?)value; }
        }
    }

    [Serializable]
    public sealed class FieldFilterTransmission : HP.Datastore.Common.FieldFilter, HP.Datastore.Common.IFieldFilter
    {
        public FieldFilterTransmission() : base("Transmission") { }
        public string Transmission { get; set; }
        object HP.Datastore.Common.IFieldFilter.Value
        {
            get { return this.Transmission; }
            set { this.Transmission = (string)value; }
        }
    }

    [Serializable]
    public sealed class FieldFilterYear : HP.Datastore.Common.FieldFilter, HP.Datastore.Common.IFieldFilter
    {
        public FieldFilterYear() : base("Year") { }
        public int? Year { get; set; }
        object HP.Datastore.Common.IFieldFilter.Value
        {
            get { return this.Year; }
            set { this.Year = (int?)value; }
        }
    }

    [Serializable]
    public sealed class FieldFilterCity : HP.Datastore.Common.FieldFilter, HP.Datastore.Common.IFieldFilter
    {
        public FieldFilterCity() : base("City") { }
        public string City { get; set; }
        object HP.Datastore.Common.IFieldFilter.Value
        {
            get { return this.City; }
            set { this.City = (string)value; }
        }
    }

    [Serializable]
    public sealed class FieldFilterLocation : HP.Datastore.Common.GeoCodeFieldFilter, HP.Datastore.Common.IFieldFilter
    {
        public FieldFilterLocation() : base("Location") { }
    }

    [Serializable]
    public sealed class FieldFilterMetro : HP.Datastore.Common.FieldFilter, HP.Datastore.Common.IFieldFilter
    {
        public FieldFilterMetro() : base("Metro") { }
        public string Metro { get; set; }
        object HP.Datastore.Common.IFieldFilter.Value
        {
            get { return this.Metro; }
            set { this.Metro = (string)value; }
        }
    }

    [Serializable]
    public sealed class FieldFilterPostDate : HP.Datastore.Common.FieldFilter, HP.Datastore.Common.IFieldFilter
    {
        public FieldFilterPostDate() : base("PostDate") { }
        public DateTime? PostDate { get; set; }
        object HP.Datastore.Common.IFieldFilter.Value
        {
            get { return this.PostDate; }
            set { this.PostDate = (DateTime?)value; }
        }
    }

    [Serializable]
    public sealed class FieldFilterZIP : HP.Datastore.Common.FieldFilter, HP.Datastore.Common.IFieldFilter
    {
        public FieldFilterZIP() : base("ZIP") { }
        public string ZIP { get; set; }
        object HP.Datastore.Common.IFieldFilter.Value
        {
            get { return this.ZIP; }
            set { this.ZIP = (string)value; }
        }
    }

    [Serializable]
    public sealed class FieldFilterVIN : HP.Datastore.Common.FieldFilter, HP.Datastore.Common.IFieldFilter
    {
        public FieldFilterVIN() : base("VIN") { }
        public string VIN { get; set; }
        object HP.Datastore.Common.IFieldFilter.Value
        {
            get { return this.VIN; }
            set { this.VIN = (string)value; }
        }
    }

    [Serializable]
    public sealed class FieldFilterUserId : HP.Datastore.Common.FieldFilter, HP.Datastore.Common.IFieldFilter
    {
        public FieldFilterUserId() : base("UserId") { }
        public int? UserId { get; set; }
        object HP.Datastore.Common.IFieldFilter.Value
        {
            get { return this.UserId; }
            set { this.UserId = (int?)value; }
        }
    }

    [Serializable]
    public sealed class FieldFilterTitle : HP.Datastore.Common.FieldFilter, HP.Datastore.Common.IFieldFilter
    {
        public FieldFilterTitle() : base("Title") { }
        public string Title { get; set; }
        object HP.Datastore.Common.IFieldFilter.Value
        {
            get { return this.Title; }
            set { this.Title = (string)value; }
        }
    }

    [Serializable]
    public sealed class FieldFilterFuelType : HP.Datastore.Common.FieldFilter, HP.Datastore.Common.IFieldFilter
    {
        public FieldFilterFuelType() : base("FuelType") { }
        public string FuelType { get; set; }
        object HP.Datastore.Common.IFieldFilter.Value
        {
            get { return this.FuelType; }
            set { this.FuelType = (string)value; }
        }
    }

    [Serializable]
    public sealed class FieldFilterDescription : HP.Datastore.Common.FieldFilter, HP.Datastore.Common.IFieldFilter
    {
        public FieldFilterDescription() : base("Description") { }
        public string Description { get; set; }
        object HP.Datastore.Common.IFieldFilter.Value
        {
            get { return this.Description; }
            set { this.Description = (string)value; }
        }
    }

    [Serializable]
    public sealed class FieldFilterDealer : HP.Datastore.Common.FieldFilter, HP.Datastore.Common.IFieldFilter
    {
        public FieldFilterDealer() : base("Dealer") { }
        public string Dealer { get; set; }
        object HP.Datastore.Common.IFieldFilter.Value
        {
            get { return this.Dealer; }
            set { this.Dealer = (string)value; }
        }
    }

    [Serializable]
    public sealed class FieldFilterBodyType : HP.Datastore.Common.FieldFilter, HP.Datastore.Common.IFieldFilter
    {
        public FieldFilterBodyType() : base("BodyType") { }
        public string BodyType { get; set; }
        object HP.Datastore.Common.IFieldFilter.Value
        {
            get { return this.BodyType; }
            set { this.BodyType = (string)value; }
        }
    }

    #endregion

    #region Sorting

    [Serializable]
    public sealed class FieldSortAutoID : HP.Datastore.Common.FieldSort, HP.Datastore.Common.IFieldSort
    {
        public FieldSortAutoID() : base("AutoID") { }
    }

    [Serializable]
    public sealed class FieldSortMake : HP.Datastore.Common.FieldSort, HP.Datastore.Common.IFieldSort
    {
        public FieldSortMake() : base("Make") { }
    }

    [Serializable]
    public sealed class FieldSortModel : HP.Datastore.Common.FieldSort, HP.Datastore.Common.IFieldSort
    {
        public FieldSortModel() : base("Model") { }
    }

    [Serializable]
    public sealed class FieldSortState : HP.Datastore.Common.FieldSort, HP.Datastore.Common.IFieldSort
    {
        public FieldSortState() : base("State") { }
    }

    [Serializable]
    public sealed class FieldSortExteriorColor : HP.Datastore.Common.FieldSort, HP.Datastore.Common.IFieldSort
    {
        public FieldSortExteriorColor() : base("ExteriorColor") { }
    }

    [Serializable]
    public sealed class FieldSortInteriorColor : HP.Datastore.Common.FieldSort, HP.Datastore.Common.IFieldSort
    {
        public FieldSortInteriorColor() : base("InteriorColor") { }
    }

    [Serializable]
    public sealed class FieldSortCondition : HP.Datastore.Common.FieldSort, HP.Datastore.Common.IFieldSort
    {
        public FieldSortCondition() : base("Condition") { }
    }

    [Serializable]
    public sealed class FieldSortMileage : HP.Datastore.Common.FieldSort, HP.Datastore.Common.IFieldSort
    {
        public FieldSortMileage() : base("Mileage") { }
    }

    [Serializable]
    public sealed class FieldSortPrice : HP.Datastore.Common.FieldSort, HP.Datastore.Common.IFieldSort
    {
        public FieldSortPrice() : base("Price") { }
    }

    [Serializable]
    public sealed class FieldSortTransmission : HP.Datastore.Common.FieldSort, HP.Datastore.Common.IFieldSort
    {
        public FieldSortTransmission() : base("Transmission") { }
    }

    [Serializable]
    public sealed class FieldSortYear : HP.Datastore.Common.FieldSort, HP.Datastore.Common.IFieldSort
    {
        public FieldSortYear() : base("Year") { }
    }

    [Serializable]
    public sealed class FieldSortCity : HP.Datastore.Common.FieldSort, HP.Datastore.Common.IFieldSort
    {
        public FieldSortCity() : base("City") { }
    }

    [Serializable]
    public sealed class FieldSortMetro : HP.Datastore.Common.FieldSort, HP.Datastore.Common.IFieldSort
    {
        public FieldSortMetro() : base("Metro") { }
    }

    [Serializable]
    public sealed class FieldSortPostDate : HP.Datastore.Common.FieldSort, HP.Datastore.Common.IFieldSort
    {
        public FieldSortPostDate() : base("PostDate") { }
    }

    [Serializable]
    public sealed class FieldSortZIP : HP.Datastore.Common.FieldSort, HP.Datastore.Common.IFieldSort
    {
        public FieldSortZIP() : base("ZIP") { }
    }

    [Serializable]
    public sealed class FieldSortVIN : HP.Datastore.Common.FieldSort, HP.Datastore.Common.IFieldSort
    {
        public FieldSortVIN() : base("VIN") { }
    }

    [Serializable]
    public sealed class FieldSortUserId : HP.Datastore.Common.FieldSort, HP.Datastore.Common.IFieldSort
    {
        public FieldSortUserId() : base("UserId") { }
    }

    [Serializable]
    public sealed class FieldSortTitle : HP.Datastore.Common.FieldSort, HP.Datastore.Common.IFieldSort
    {
        public FieldSortTitle() : base("Title") { }
    }

    [Serializable]
    public sealed class FieldSortFuelType : HP.Datastore.Common.FieldSort, HP.Datastore.Common.IFieldSort
    {
        public FieldSortFuelType() : base("FuelType") { }
    }

    [Serializable]
    public sealed class FieldSortDescription : HP.Datastore.Common.FieldSort, HP.Datastore.Common.IFieldSort
    {
        public FieldSortDescription() : base("Description") { }
    }

    [Serializable]
    public sealed class FieldSortDealer : HP.Datastore.Common.FieldSort, HP.Datastore.Common.IFieldSort
    {
        public FieldSortDealer() : base("Dealer") { }
    }

    [Serializable]
    public sealed class FieldSortBodyType : HP.Datastore.Common.FieldSort, HP.Datastore.Common.IFieldSort
    {
        public FieldSortBodyType() : base("BodyType") { }
    }

    #endregion

    [Serializable]
    public partial class ListingResults : HP.Datastore.Common.IListingResults
    {
        public ListingResults()
        {
            this.Query = new ListingQuery();
            this.DimensionList = new List<HP.Datastore.Common.DimensionItem>();
            this.AllDimensions = new DimensionStore(this);
            this.RecordList = new List<ListingItem>();
            this.Diagnostics = new QueryDiagnostics();
        }

        internal ListingResults(HP.Datastore.Common.DataQueryResults results)
            : this()
        {
            if (!ValidVersion(results))
            {
                throw new HP.Datastore.Common.Exceptions.APIVersionException(this.Diagnostics.VersionHash, results.VersionHash);
            }

            this.Query = new ListingQuery(results);
            this.DimensionList = new List<HP.Datastore.Common.DimensionItem>(results.DimensionList);
            this.AllDimensions = new DimensionStore(this);
            this.TotalRecordCount = results.TotalRecordCount;
            if (results.DerivedFieldList != null)
            {
                this.DerivedFieldList = new List<IDerivedFieldValue>();
                foreach (var field in results.DerivedFieldList.ToList())
                {
                    var newItem = new ListingDerivedFieldValue()
                    {
                        Action = field.Action,
                        Value = field.Value,
                    };
                    switch (field.Field)
                    {
                        case "AutoID": newItem.Field = ListingItem.FieldConstants.AutoID; break;
                        case "Make": newItem.Field = ListingItem.FieldConstants.Make; break;
                        case "Model": newItem.Field = ListingItem.FieldConstants.Model; break;
                        case "State": newItem.Field = ListingItem.FieldConstants.State; break;
                        case "ExteriorColor": newItem.Field = ListingItem.FieldConstants.ExteriorColor; break;
                        case "InteriorColor": newItem.Field = ListingItem.FieldConstants.InteriorColor; break;
                        case "Condition": newItem.Field = ListingItem.FieldConstants.Condition; break;
                        case "Mileage": newItem.Field = ListingItem.FieldConstants.Mileage; break;
                        case "Price": newItem.Field = ListingItem.FieldConstants.Price; break;
                        case "Transmission": newItem.Field = ListingItem.FieldConstants.Transmission; break;
                        case "Year": newItem.Field = ListingItem.FieldConstants.Year; break;
                        case "City": newItem.Field = ListingItem.FieldConstants.City; break;
                        case "Location": newItem.Field = ListingItem.FieldConstants.Location; break;
                        case "Metro": newItem.Field = ListingItem.FieldConstants.Metro; break;
                        case "PostDate": newItem.Field = ListingItem.FieldConstants.PostDate; break;
                        case "ZIP": newItem.Field = ListingItem.FieldConstants.ZIP; break;
                        case "VIN": newItem.Field = ListingItem.FieldConstants.VIN; break;
                        case "UserId": newItem.Field = ListingItem.FieldConstants.UserId; break;
                        case "Title": newItem.Field = ListingItem.FieldConstants.Title; break;
                        case "FuelType": newItem.Field = ListingItem.FieldConstants.FuelType; break;
                        case "Description": newItem.Field = ListingItem.FieldConstants.Description; break;
                        case "Dealer": newItem.Field = ListingItem.FieldConstants.Dealer; break;
                        case "BodyType": newItem.Field = ListingItem.FieldConstants.BodyType; break;
                    }
                    this.DerivedFieldList.Add(newItem);
                }
            }

            if (results.Query.RecordsPerPage > 0)
                this.TotalPageCount = (results.TotalRecordCount / results.Query.RecordsPerPage) + (results.TotalRecordCount % results.Query.RecordsPerPage == 0 ? 0 : 1);

            foreach (var d in this.DimensionList)
            {
                this.AllDimensions.MasterList.Add((DimensionItem)((ICloneable)d).Clone());
            }

            if (results.RecordList != null)
            {
                foreach (var record in results.RecordList)
                {
                    var item = new ListingItem(record, this, results.Fieldset);
                    this.RecordList.Add(item);
                }

                var keepRefinements = new List<long>();
                if (!string.IsNullOrEmpty(results.Query.NonParsedFieldList["ar"]))
                {
                    var arr = results.Query.NonParsedFieldList["ar"].Split(new char[] { '+', ' ' });
                    foreach (var s in arr)
                    {
                        long didx;
                        if (long.TryParse(s, out didx))
                            keepRefinements.Add(didx);
                    }
                }
                this.DimensionList.RemoveAll(x => x.RefinementList.Count <= 1 && !keepRefinements.Contains(x.DIdx));
            }
            this.Diagnostics.ComputeTime = results.ComputeTime;
        }

        public List<HP.Datastore.Common.DimensionItem> DimensionList { get; private set; }
        public ListingQuery Query { get; private set; }
        public List<ListingItem> RecordList { get; private set; }
        public List<HP.Datastore.Common.IDerivedFieldValue> DerivedFieldList { get; private set; }
        public int TotalRecordCount { get; private set; }
        public int TotalPageCount { get; private set; }
        public DimensionStore AllDimensions { get; private set; }
        public QueryDiagnostics Diagnostics { get; private set; }

        #region IListingResults Members

        IListingQuery IListingResults.Query
        {
            get { return this.Query; }
        }

        List<IListingItem> IListingResults.RecordList
        {
            get { return this.RecordList.Cast<IListingItem>().ToList(); }
        }

        #endregion

        private bool ValidVersion(HP.Datastore.Common.DataQueryResults results)
        {
            if (results.Fieldset == null) return true;
            var foundCount = 0;
            foreach (var field in results.Fieldset)
            {
                switch (field.Name)
                {
                    case "AutoID": foundCount++; break;
                    case "Make": foundCount++; break;
                    case "Model": foundCount++; break;
                    case "State": foundCount++; break;
                    case "ExteriorColor": foundCount++; break;
                    case "InteriorColor": foundCount++; break;
                    case "Condition": foundCount++; break;
                    case "Mileage": foundCount++; break;
                    case "Price": foundCount++; break;
                    case "Transmission": foundCount++; break;
                    case "Year": foundCount++; break;
                    case "City": foundCount++; break;
                    case "Location": foundCount++; break;
                    case "Metro": foundCount++; break;
                    case "PostDate": foundCount++; break;
                    case "ZIP": foundCount++; break;
                    case "VIN": foundCount++; break;
                    case "UserId": foundCount++; break;
                    case "Title": foundCount++; break;
                    case "FuelType": foundCount++; break;
                    case "Description": foundCount++; break;
                    case "Dealer": foundCount++; break;
                    case "BodyType": foundCount++; break;
                }
            }
            return (foundCount == 23);
        }

    }

    public partial class QueryDiagnostics
    {
        internal QueryDiagnostics()
        {
            this.VersionHash = 450435705;
        }

        public long ComputeTime { get; internal set; }
        public long VersionHash { get; private set; }
        public long ReturnedHash { get; private set; }

    }

    [Serializable]
    public partial class DimensionStore : HP.Datastore.Common.IDimensionStore
    {

        #region Dimension Names

        public const string Dimension_BodyType = "BodyType";
        public const string Dimension_Condition = "Condition";
        public const string Dimension_ExteriorColor = "ExteriorColor";
        public const string Dimension_InteriorColor = "InteriorColor";
        public const string Dimension_Make = "Make";
        public const string Dimension_Metro = "Metro";
        public const string Dimension_Mileage = "Mileage";
        public const string Dimension_Model = "Model";
        public const string Dimension_Price = "Price";
        public const string Dimension_State = "State";
        public const string Dimension_Transmission = "Transmission";
        public const string Dimension_Year = "Year";

        public enum DimensionConstants
        {
            BodyType,
            Condition,
            ExteriorColor,
            InteriorColor,
            Make,
            Metro,
            Mileage,
            Model,
            Price,
            State,
            Transmission,
            Year,
        }

        #endregion

        private ListingResults _results = null;
        public DimensionStore(ListingResults results)
        {
            _results = results;
            this.MasterList = new List<DimensionItem>();
        }

        public List<DimensionItem> MasterList { get; private set; }

        IEnumerable<DimensionItem> HP.Datastore.Common.IDimensionStore.MasterList
        {
            get { return this.MasterList; }
        }

        public HP.Datastore.Common.DimensionItem BodyTypeDimension
        {
            get { return this.MasterList.FirstOrDefault(x => x.Name == "BodyType"); }
        }
        public HP.Datastore.Common.DimensionItem ConditionDimension
        {
            get { return this.MasterList.FirstOrDefault(x => x.Name == "Condition"); }
        }
        public HP.Datastore.Common.DimensionItem ExteriorColorDimension
        {
            get { return this.MasterList.FirstOrDefault(x => x.Name == "ExteriorColor"); }
        }
        public HP.Datastore.Common.DimensionItem InteriorColorDimension
        {
            get { return this.MasterList.FirstOrDefault(x => x.Name == "InteriorColor"); }
        }
        public HP.Datastore.Common.DimensionItem MakeDimension
        {
            get { return this.MasterList.FirstOrDefault(x => x.Name == "Make"); }
        }
        public HP.Datastore.Common.DimensionItem MetroDimension
        {
            get { return this.MasterList.FirstOrDefault(x => x.Name == "Metro"); }
        }
        public HP.Datastore.Common.DimensionItem MileageDimension
        {
            get { return this.MasterList.FirstOrDefault(x => x.Name == "Mileage"); }
        }
        public HP.Datastore.Common.DimensionItem ModelDimension
        {
            get { return this.MasterList.FirstOrDefault(x => x.Name == "Model"); }
        }
        public HP.Datastore.Common.DimensionItem PriceDimension
        {
            get { return this.MasterList.FirstOrDefault(x => x.Name == "Price"); }
        }
        public HP.Datastore.Common.DimensionItem StateDimension
        {
            get { return this.MasterList.FirstOrDefault(x => x.Name == "State"); }
        }
        public HP.Datastore.Common.DimensionItem TransmissionDimension
        {
            get { return this.MasterList.FirstOrDefault(x => x.Name == "Transmission"); }
        }
        public HP.Datastore.Common.DimensionItem YearDimension
        {
            get { return this.MasterList.FirstOrDefault(x => x.Name == "Year"); }
        }

        public HP.Datastore.Common.DimensionItem GetDimension(DimensionConstants type)
        {
            switch (type)
            {
                case DimensionConstants.BodyType:
                    return this.BodyTypeDimension; break;
                case DimensionConstants.Condition:
                    return this.ConditionDimension; break;
                case DimensionConstants.ExteriorColor:
                    return this.ExteriorColorDimension; break;
                case DimensionConstants.InteriorColor:
                    return this.InteriorColorDimension; break;
                case DimensionConstants.Make:
                    return this.MakeDimension; break;
                case DimensionConstants.Metro:
                    return this.MetroDimension; break;
                case DimensionConstants.Mileage:
                    return this.MileageDimension; break;
                case DimensionConstants.Model:
                    return this.ModelDimension; break;
                case DimensionConstants.Price:
                    return this.PriceDimension; break;
                case DimensionConstants.State:
                    return this.StateDimension; break;
                case DimensionConstants.Transmission:
                    return this.TransmissionDimension; break;
                case DimensionConstants.Year:
                    return this.YearDimension; break;
                default:
                    throw new Exception("Unknown dimension");
            }
        }

    }

    [Serializable]
    public partial class RepositoryConnection : IRepositoryConnection
    {
        //RepositoryKey: d55cd480-abe9-4c83-8d24-52ed38588bbc;

        protected Guid _repositoryId = Guid.Empty;

        public RepositoryConnection(Guid repositoryId)
        {
            _repositoryId = repositoryId;
        }

        public static System.ServiceModel.ChannelFactory<HP.Datastore.Common.IDataModel> GetFactory(string serverName)
        {
            return GetFactory(serverName, 1973);
        }

        public static System.ServiceModel.ChannelFactory<HP.Datastore.Common.IDataModel> GetFactory(string serverName, int port)
        {
            var myBinding = new CompressedNetTcpBinding();
            myBinding.Security.Mode = SecurityMode.None;
            myBinding.MaxBufferPoolSize = 2147483647;
            myBinding.MaxBufferSize = 2147483647;
            myBinding.MaxConnections = 10;
            myBinding.MaxReceivedMessageSize = 2147483647;
            myBinding.ReaderQuotas.MaxDepth = 2147483647;
            myBinding.ReaderQuotas.MaxStringContentLength = 2147483647;
            myBinding.ReaderQuotas.MaxArrayLength = 2147483647;
            myBinding.ReaderQuotas.MaxBytesPerRead = 2147483647;
            myBinding.ReaderQuotas.MaxNameTableCharCount = 2147483647;
            var endpoint = new EndpointAddress("net.tcp://" + serverName + ":" + port + "/__datastore_engine");
            return new System.ServiceModel.ChannelFactory<HP.Datastore.Common.IDataModel>(myBinding, endpoint);
        }

        public void Clear(HP.Datastore.Common.IDataModel service, UserCredentials credentials)
        {
            var errorList = service.Clear(_repositoryId, credentials);
            if (errorList != null && errorList.Length > 0)
            {
                throw new Exception(errorList.First());
            }
        }

        public RepositorySchema GetSchema(UserCredentials credentials, HP.Datastore.Common.IDataModel service)
        {
            return service.GetSchema(_repositoryId, credentials);
        }

        public void UpdateSchema(RepositorySchema schema, UserCredentials credentials, HP.Datastore.Common.IDataModel service)
        {
            if (schema == null) throw new Exception("The schema is not set.");
            if (schema.ID != _repositoryId) throw new Exception("The schema does not match the RepositoryID.");
            var errorList = service.UpdateSchema(schema, credentials);
            if (errorList != null && errorList.Length > 0)
            {
                throw new Exception(errorList.First());
            }
        }

        public void UpdateData(RepositorySchema schema, ListingItem item, UserCredentials credentials, HP.Datastore.Common.IDataModel service)
        {
            UpdateData(schema, new List<ListingItem>() { item }, credentials, service);
        }

        public void UpdateData(RepositorySchema schema, IEnumerable<ListingItem> list, UserCredentials credentials, HP.Datastore.Common.IDataModel service)
        {
            if (schema == null) throw new Exception("The schema is not set.");
            if (schema.ID != _repositoryId) throw new Exception("The schema does not match the RepositoryID.");
            var l = new List<HP.Datastore.Common.DataItem>();
            list.ToList().ForEach(x => l.Add(x.ToTransfer(schema)));
            var errorList = service.UpdateData(schema, l, credentials);
            if (errorList != null && errorList.Length > 0)
            {
                throw new Exception(errorList.First());
            }
        }

        public bool IsValidFormat(ListingItem item, UserCredentials credentials, HP.Datastore.Common.IDataModel service)
        {
            if (service.RepositoryExists(_repositoryId, credentials))
            {
                var schema = service.GetSchema(_repositoryId, credentials);
                return service.IsValidFormat(_repositoryId, item.ToTransfer(schema), credentials);
            }
            return false;
        }

        public void DeleteData(RepositorySchema schema, ListingItem item, UserCredentials credentials, HP.Datastore.Common.IDataModel service)
        {
            DeleteData(schema, new List<ListingItem>() { item }, credentials, service);
        }

        public void DeleteData(RepositorySchema schema, IEnumerable<ListingItem> list, UserCredentials credentials, HP.Datastore.Common.IDataModel service)
        {
            if (schema == null) throw new Exception("The schema is not set.");
            if (schema.ID != _repositoryId) throw new Exception("The schema does not match the RepositoryID.");
            var l = new List<HP.Datastore.Common.DataItem>();
            list.ToList().ForEach(x => l.Add(x.ToTransfer(schema)));
            var errorList = service.DeleteItems(schema, l, credentials);
            if (errorList != null && errorList.Length > 0)
            {
                throw new Exception(errorList.First());
            }
        }

        public void DeleteData(RepositorySchema schema, ListingQuery query, HP.Datastore.Common.IDataModel service)
        {
            if (schema == null) throw new Exception("The schema is not set.");
            if (schema.ID != _repositoryId) throw new Exception("The schema does not match the RepositoryID.");
            var errorList = service.DeleteData(schema, query.ToTransfer(), query.Credentials);
            if (errorList != null && errorList.Length > 0)
            {
                throw new Exception(errorList.First());
            }
        }

        public ListingResults QueryData(ListingQuery query, HP.Datastore.Common.IDataModel service)
        {
            var t = service.Query(_repositoryId, query.ToTransfer());
            if (t.ErrorList != null && t.ErrorList.Length > 0)
            {
                throw new Exception(t.ErrorList.First());
            }
            return new ListingResults(t);
        }

        #region IRepositoryConnection Members

        void IRepositoryConnection.UpdateData(RepositorySchema schema, IListingItem item, UserCredentials credentials, IDataModel service)
        {
            this.UpdateData(schema, (ListingItem)item, credentials, service);
        }

        void IRepositoryConnection.UpdateData(RepositorySchema schema, IEnumerable<IListingItem> list, UserCredentials credentials, IDataModel service)
        {
            this.UpdateData(schema, list.Cast<ListingItem>(), credentials, service);
        }

        bool IRepositoryConnection.IsValidFormat(IListingItem item, UserCredentials credentials, IDataModel service)
        {
            return IsValidFormat((ListingItem)item, credentials, service);
        }

        void IRepositoryConnection.DeleteData(RepositorySchema schema, IListingItem item, UserCredentials credentials, IDataModel service)
        {
            this.DeleteData(schema, (ListingItem)item, credentials, service);
        }

        void IRepositoryConnection.DeleteData(RepositorySchema schema, IEnumerable<IListingItem> list, UserCredentials credentials, IDataModel service)
        {
            this.DeleteData(schema, list.Cast<ListingItem>(), credentials, service);
        }

        void IRepositoryConnection.DeleteData(RepositorySchema schema, IListingQuery query, IDataModel service)
        {
            this.DeleteData(schema, (ListingQuery)query, service);
        }

        IListingResults IRepositoryConnection.QueryData(IListingQuery query, IDataModel service)
        {
            return this.QueryData((ListingQuery)query, service);
        }

        #endregion

    }

}
